#include "common.h"

value loadmodule(const char *file, value *exc) {
field fname = val_id("loadmodule");
value args[2];
args[0] = alloc_string(file);
args[1] = loader;
return val_callEx(loader, val_field(loader, fname), args, 2, exc);
}

value loadprim(const char *prim, int nargs, value *exc) {
field fname = val_id("loadprim");
value args[2];
args[0] = alloc_string(prim);
args[1] = alloc_int(nargs);
return val_callEx(loader, val_field(loader, fname), args, 2, exc);
}

PyObject *Neko_globals(PyObject *self, PyObject *args) {
return ConvNeko2Py(loader);
}

PyObject *Neko_loadprim(PyObject *self, PyObject *args) {
value exc = NULL;
value result = loadprim(PyString_AsString(PyTuple_GetItem(args, 0)), PyInt_AsLong(PyTuple_GetItem(args, 1)), &exc);
if( exc != NULL ) {
    buffer b = alloc_buffer(NULL);
    val_buffer(b, exc);
    PyErr_SetString(PyExc_RuntimeError, val_string(buffer_to_string(b)));
    return NULL;
	}
return ConvNeko2Py(result);
}

PyObject *Neko_loadmodule(PyObject *self, PyObject *args) {
value exc = NULL;
value result = loadmodule(PyString_AsString(PyTuple_GetItem(args, 0)), &exc);
if( exc != NULL ) {
    buffer b = alloc_buffer(NULL);
    val_buffer(b, exc);
    PyErr_SetString(PyExc_RuntimeError, val_string(buffer_to_string(b)));
    return NULL;
	}
return ConvNeko2Py(result);
}

static PyMethodDef neko_methods[] = {
	{"globals",		Neko_globals,	METH_NOARGS,		NULL},
	{"loadprim",	Neko_loadprim,	METH_VARARGS,		NULL},
	{"loadmodule",	Neko_loadmodule,	METH_VARARGS,		NULL},
	{NULL,			NULL} 
};

DL_EXPORT(void) init_neko(void) {
	PyObject *m;

	if(loader==NULL) {
		neko_vm *vm;
		neko_global_init(NULL);
		vm = neko_vm_alloc(NULL);
		neko_vm_select(vm);
		loader = neko_default_loader(NULL,0);
	}

	m = Py_InitModule("_neko", neko_methods);
} 